import { emptyDefaultImg, apiEndStatus } from '@/utils/config'
import { flatten, getEventDataset, runCallback } from '../utils/util'

/**
 * loadPageErr
 * loadPageEnd
 * fromatList
 * listApiFn
 * customData { listKey, params, listAmount, listConduit }
 */
module.exports = Behavior({
  data: {
    scrollTop: 0,
    page: 1,
    list: [],
    loading: false,
    firsting: true,
    ended: false,
    freshing: false,
    endStatus: {}
  },
  methods: {
    getSplitList (list = [], conduit = 1) {
      if (conduit === 1) return list

      return list.reduce((splitList, item, i) => {
        const index = i % conduit

        if (!splitList[index]) splitList[index] = []
        splitList[index].push(item)

        return splitList
      }, [])
    },
    getSetDataSplitList (list = [], page = 1, freshing) {
      return list.reduce((obj, item, i) => {
        const key = freshing ? `list[${i}]` : `list[${i}][${page - 1}]`
        obj[key] = item
        return obj
      }, {})
    },
    async onLoadPageRefresh () {
      await this.loadPageDataApi(true)
    },
    async loadPageData () {
      await this.loadPageDataApi()
    },
    async loadPageDataApi (freshing = false) {
      if (this.data.freshing || (!freshing && (this.data.ended || this.data.loading)) || typeof (this.listApiFn) !== 'function') return

      this.setData({
        loading: !freshing,
        freshing
      })

      const { listAmount = 20, listBeforeData } = this.customData
      let { page } = this.data
      freshing && (page = 1)

      try {
        const res = await this.listApiFn({
          noToast: true,
          data: Object.assign({ page }, this.customData.params)
        })

        let list = res.result[this.customData.listKey || 'list'] || [];
        (page === 1 && Array.isArray(listBeforeData)) && (list = listBeforeData.concat(list));
        list = typeof (this.fromatList) === 'function' ? this.fromatList(list, page, res) : list

        const { length } = list

        let listObj = {}
        const { listConduit } = this.customData

        if (listConduit && listConduit >= 2) {
          listObj = this.getSetDataSplitList(this.getSplitList(list, listConduit), page, freshing)
        } else if (freshing) {
          listObj = { list: [list] }
        } else {
          listObj = { [`list[${page - 1}]`]: list }
        }

        this.setData(Object.assign(
          {
            loading: false,
            firsting: page === 1 && length === 0,
            ended: length < listAmount,
            page: page + 1
          },
          listObj,
          freshing && { freshing: false },
          page === 1 && length === 0
          ? { endStatus: { type: 'empty', desc: '什么都没有哦~', image: emptyDefaultImg } }
          : { endStatus: { type: 'end', desc: '就这么多啦~', image: emptyDefaultImg } }
        ));
        
        (this.loadPageEnd && typeof this.loadPageEnd === 'function') && this.loadPageEnd(res.result, list, freshing)
      } catch (error) {
        this.setData({
          loading: false,
          ended: true,
          firsting: page === 1,
          freshing: false,
          endStatus: apiEndStatus(error)
        });

        (this.loadPageErr && typeof this.loadPageErr === 'function') && this.loadPageErr(error, freshing)
      }
    },
    reLoadPageStatus (callback) {
      this.setData({
        scrollTop: 0,
        page: 1,
        list: [],
        loading: false,
        firsting: true,
        freshing: false,
        ended: false,
        endStatus: {}
      }, () => {
        (callback && typeof callback === 'function') && callback()
      })
    },
    reLoadPageStatusAsync () {
      return new Promise((resolve, reject) => {
        this.setData({
          scrollTop: 0,
          page: 1,
          list: [],
          loading: false,
          firsting: true,
          freshing: false,
          ended: false,
          endStatus: {}
        }, () => {
          resolve()
        })
      })
    },
    reLoadPageData () {
      this.reLoadPageStatus(this.loadPageData)
    },
    async reLoadPageDataAsync () {
      await this.reLoadPageStatusAsync()
      await this.loadPageData()
    },
    // 手动增删列表数组的时候，判断是否为空以便显示对应状态
    isEmptyHandle () {
      const { listConduit } = this.customData
      const _list = flatten(this.data.list, listConduit && listConduit >= 2 ? 2 : 1)

      if (_list.length !== 0) return

      this.setData({
        page: 1,
        loading: false,
        firsting: true,
        ended: false,
        freshing: false,
        endStatus: { endStatus: { type: 'EMPTY', desc: '什么都没有哦~', image: emptyDefaultImg } }
      })
    },
    quickDelListItem (e) {
      const { index, i } = getEventDataset(e)

      this.delListItem(index, i)
    },
    delListItem (index, i) {
      const listChild = this.data.list[index]
      listChild.splice(i, 1)

      this.setData({
        [`list[${index}]`]: listChild
      }, () => {
        this.isEmptyHandle()
        runCallback(this.onDelListItem, { index, i })
      })
    }
  }
})
